home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / NewsWatcher 2.0d17 Source / source / collapse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-01  |  7.0 KB  |  252 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     collapse.c
  4.  
  5.     This module handles collapsing and expanding threads.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include "glob.h"
  13. #include "collapse.h"
  14. #include "draw.h"
  15. #include "menus.h"
  16. #include "resize.h"
  17. #include "util.h"
  18. #include "wind.h"
  19. #include "scroll.h"
  20.  
  21.  
  22. /*    ExpandCollapseThread expands or collapses a single thread.
  23.  
  24.     Entry:    wind = pointer to window record.
  25.             theCell = any cell in the thread to be expanded or collapsed.
  26.             
  27.     Exit:    function result = true if thead collapsed, false if expanded.
  28. */
  29.  
  30. static Boolean ExpandCollapseThread (WindowPtr wind, Cell theCell)
  31. {
  32.     TWindow **info;
  33.     ListHandle theList;
  34.     TSubject **subjectArray, theSubject;
  35.     Cell tmpCell, newCell;
  36.     long finalTicks;
  37.     short i, nextInThread, cellDataLen, cellData;
  38.     Rect inval;
  39.     
  40.     info = (TWindow**)GetWRefCon(wind);
  41.     theList = (**info).theList;
  42.     subjectArray = (**info).subjectArray;
  43.     cellDataLen = 2;
  44.     LGetCell(&cellData, &cellDataLen, theCell, theList);
  45.     theSubject = (*subjectArray)[cellData];
  46.     if (theSubject.threadOrdinal != 1) {
  47.         theCell.v -= theSubject.threadOrdinal-1;
  48.         LGetCell(&cellData, &cellDataLen, theCell, theList);
  49.         theSubject = (*subjectArray)[cellData];
  50.     }
  51.     theSubject.collapsed = !theSubject.collapsed;
  52.     nextInThread = cellData;
  53.     for (i = 0; i < theSubject.threadLength; i++) {
  54.         (*subjectArray)[nextInThread].collapsed = theSubject.collapsed;
  55.         nextInThread = (*subjectArray)[nextInThread].nextInThread;
  56.     }
  57.     (*subjectArray)[cellData].onlyRedrawTriangle = true;
  58.     (*subjectArray)[cellData].onlyRedrawCheck = false;
  59.     (*subjectArray)[cellData].drawTriangleFilled = true;
  60.     LDraw(theCell, theList);
  61.     (*subjectArray)[cellData].onlyRedrawTriangle = false;
  62.     (*subjectArray)[cellData].onlyRedrawCheck = true;
  63.     LDraw(theCell, theList);
  64.     (*subjectArray)[cellData].onlyRedrawTriangle = true;
  65.     (*subjectArray)[cellData].onlyRedrawCheck = false;
  66.     
  67.     if (theSubject.collapsed) {
  68.         LDelRow(theSubject.threadLength-1, theCell.v+1, theList);
  69.         SetPt(&tmpCell, 0, 0);
  70.         if (!LGetSelect(true, &tmpCell, theList)) 
  71.             LSetSelect(true, theCell, theList);
  72.     } else {
  73.         LDoDraw(false, theList);
  74.         LAddRow(theSubject.threadLength-1, theCell.v+1, theList);
  75.         newCell = theCell;
  76.         nextInThread = theSubject.nextInThread;
  77.         for (i = 1; i < theSubject.threadLength; i++) {
  78.             newCell.v++;
  79.             LSetCell(&nextInThread, 2, newCell, theList);
  80.             nextInThread = (*subjectArray)[nextInThread].nextInThread;
  81.         }
  82.         LDoDraw(true, theList);
  83.         inval = wind->portRect;
  84.         inval.top = (theCell.v - (**theList).visible.top + 1) *
  85.             (**theList).cellSize.v;
  86.         inval.right -= 15;
  87.         inval.bottom -= 15;
  88.         InvalRect(&inval);
  89.         HandleUpdate(wind);
  90.     }
  91.     
  92.     Delay(8, &finalTicks);
  93.     (*subjectArray)[cellData].drawTriangleFilled = false;
  94.     LDraw(theCell, theList);
  95.     (*subjectArray)[cellData].onlyRedrawTriangle = false;
  96.     return theSubject.collapsed;
  97. }
  98.  
  99.  
  100. /*    RezoomWindow rezooms the window if a thread has been expanded and
  101.     the "Zoom windows" preference is turned on. */
  102.     
  103. static void RezoomWindow (WindowPtr wind, Boolean expanded)
  104. {
  105.     TWindow **info;
  106.     ListHandle theList;
  107.     ControlHandle scrollBar;
  108.     
  109.     info = (TWindow**)GetWRefCon(wind);
  110.     theList = (**info).theList;
  111.     scrollBar = (**theList).vScroll;
  112.     if (expanded && gPrefs.zoomWindows && GetCtlMax(scrollBar) > 0) {
  113.         DoZoom(wind, inZoomOut);
  114.     } else {
  115.         SetWindowNeedsZooming(wind);
  116.     }    
  117. }
  118.  
  119.  
  120. /*    DoExpandCollapseSelectedThread expands or collapses just the currently 
  121.     selected thread in a subject window.
  122.     
  123.     Entry:    wind = pointer to subject window. 
  124. */
  125.     
  126. void DoExpandCollapseSelectedThread (WindowPtr wind)
  127. {
  128.     TWindow **info;
  129.     ListHandle theList;
  130.     TSubject **subjectArray;
  131.     Cell theCell, tmpCell;
  132.     short cellDataLen, cellData;
  133.     TSubject theSubject;
  134.     Boolean collapsed;
  135.  
  136.     SetPort(wind);
  137.     info = (TWindow**)GetWRefCon(wind);
  138.     theList = (**info).theList;
  139.     subjectArray = (**info).subjectArray;
  140.     SetPt(&theCell, 0, 0);
  141.     if (!LGetSelect(true, &theCell, theList)) return;
  142.     tmpCell = theCell;
  143.     tmpCell.v++;
  144.     if (LGetSelect(true, &tmpCell, theList)) return;
  145.     cellDataLen = 2;
  146.     LGetCell(&cellData, &cellDataLen, theCell, theList);
  147.     theSubject = (*subjectArray)[cellData];
  148.     if (theSubject.threadLength <= 1) return;
  149.     collapsed = ExpandCollapseThread(wind, theCell);
  150.     RezoomWindow(wind, !collapsed);
  151. }
  152.  
  153.  
  154. /*    TriangleClick handles mouse-downs on the expand/collapse triangle
  155.     thread controls in subject windows.
  156.     
  157.     Entry:    wind = pointer to subject window.
  158.             where = location of mouse down in local coordinates.
  159. */
  160.  
  161. Boolean TriangleClick (WindowPtr wind, Point where)
  162. {
  163.     TWindow **info;
  164.     ListHandle theList;
  165.     TSubject **subjectArray, theSubject;
  166.     FontInfo fontInfo;
  167.     Cell theCell;
  168.     short cellData, cellDataLen;
  169.     Rect hitRect;
  170.     Boolean inHitRect, newInHitRect;
  171.     short visTop, cellHeight;
  172.     Boolean collapsed;
  173.  
  174.     info = (TWindow**)GetWRefCon(wind);
  175.     theList = (**info).theList;
  176.     visTop = (**theList).visible.top;
  177.     cellHeight = (**theList).cellSize.v;
  178.     subjectArray = (**info).subjectArray;
  179.     GetFontInfo(&fontInfo);
  180.     SetRect(&hitRect, 0, 0, (**theList).indent.h + fontInfo.ascent, 0);
  181.     if (where.h > hitRect.right) return false;
  182.     theCell.h = 0;
  183.     theCell.v = where.v/cellHeight + visTop;
  184.     if (theCell.v >= (**theList).dataBounds.bottom) return false;
  185.     cellDataLen = 2;
  186.     LGetCell(&cellData, &cellDataLen, theCell, theList);
  187.     theSubject = (*subjectArray)[cellData];
  188.     if (theSubject.threadLength == 1 || theSubject.threadOrdinal > 1) 
  189.         return false;
  190.     (*subjectArray)[cellData].drawTriangleFilled = inHitRect =  true;
  191.     (*subjectArray)[cellData].onlyRedrawTriangle = true;
  192.     LDraw(theCell, theList);
  193.     hitRect.top = (theCell.v - visTop) * cellHeight;
  194.     hitRect.bottom = hitRect.top + cellHeight;
  195.     while (StillDown()) {
  196.         GetMouse(&where);
  197.         newInHitRect = PtInRect(where, &hitRect);
  198.         if (newInHitRect != inHitRect) {
  199.             (*subjectArray)[cellData].drawTriangleFilled = newInHitRect;
  200.             LDraw(theCell, theList);
  201.             inHitRect = newInHitRect;
  202.         }
  203.     }
  204.     if (!inHitRect) {
  205.         (*subjectArray)[cellData].drawTriangleFilled = false;
  206.         (*subjectArray)[cellData].onlyRedrawTriangle = false;
  207.         return true;
  208.     }
  209.     collapsed = ExpandCollapseThread(wind, theCell);
  210.     RezoomWindow(wind, !collapsed);
  211.     return true;
  212. }
  213.  
  214. void ExpandCollapseKey (WindowPtr wind, char theChar)
  215. {
  216.     TWindow **info;
  217.     ListHandle theList;
  218.     TSubject **subjectArray;
  219.     Cell theCell;
  220.     short cellDataLen, cellData;
  221.     TSubject theSubject;
  222.     Boolean expanded = false;
  223.     Boolean changed = false;
  224.  
  225.     SetPort(wind);
  226.     info = (TWindow**)GetWRefCon(wind);
  227.     theList = (**info).theList;
  228.     subjectArray = (**info).subjectArray;
  229.  
  230.     SetPt(&theCell, 0, 0);
  231.     while (true) {
  232.         if (!LGetSelect(true, &theCell, theList)) break;
  233.         cellDataLen = 2;
  234.         LGetCell(&cellData, &cellDataLen, theCell, theList);
  235.         theSubject = (*subjectArray)[cellData];
  236.         if (theSubject.threadLength > 1)
  237.             if (theSubject.collapsed && theChar == rightArrow ||
  238.                 !theSubject.collapsed && theChar == leftArrow) 
  239.             { 
  240.                 ExpandCollapseThread(wind, theCell);
  241.                 changed = true;
  242.                 if (theChar == rightArrow) expanded = true;
  243.             }
  244.         theCell.v++;
  245.     }
  246.     if (changed) RezoomWindow(wind, expanded);
  247. }
  248.  
  249.  
  250.  
  251.  
  252.